/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fsd.semana1.casa.echoselector;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;

/**
 *
 * @author nfsa
 */
public class EchoSelectorServerMain {


    public static void echoServerMain() throws Exception
    {
        ServerSocketChannel server = SelectorProvider.provider().openServerSocketChannel();
        server.configureBlocking(false);
        server.socket().bind(new InetSocketAddress(12345));

        Selector selector = Selector.open();
        server.register(selector, SelectionKey.OP_ACCEPT);

        while (selector.isOpen())
        {
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext())
            {
                SelectionKey key = iterator.next();
                iterator.remove();
                if (key.isAcceptable())
                {
                    SocketChannel client = server.accept();
                    client.configureBlocking(false);
                    ByteBuffer source = ByteBuffer.allocate(256);
                    SelectionKey key2 =
                            client.register(selector, SelectionKey.OP_READ);// | SelectionKey.OP_WRITE);
                    key2.attach(source);
                }
                if (key.isReadable())
                {
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer output = (ByteBuffer) key.attachment();
                    int received = client.read(output);
                    if (received <= 0)
                    {
                        key.cancel();
                        key.channel().close();
                    }
                    else
                    {
                        key.interestOps(SelectionKey.OP_WRITE);
                    }
                }
                if (key.isValid() && key.isWritable())
                {
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer output = (ByteBuffer) key.attachment();
                    output.flip();
                    client.write(output);
                    output.compact();
                    key.interestOps(SelectionKey.OP_READ);
                }
            }
        }
    }
}
